home *** CD-ROM | disk | FTP | other *** search
- #include "list.h"
-
- #define THIS LinkedList
- #define BASE SeqCltn
- DEFINE_CLASS(LinkedList,SeqCltn);
-
- LinkedList::LinkedList()
- {
- firstLink = lastLink = (Link*)nil;
- count = 0;
- }
-
- bool LinkedList::operator==(const LinkedList& ll) const
- {
- if (count != ll.count) return NO;
- else {
- register Link* p = firstLink;
- register Link* q = ll.firstLink;
- while (p != (Link*)nil) {
- if (!(p->isEqual(*q))) return NO;
- p = p->nextLink();
- q = q->nextLink();
- }
- }
- return YES;
- }
-
- Object* LinkedList::add(const Object& ob)
- {
- assertArgClass(ob,class_Link,"add");
- register Link* lnk = (Link*)&ob;
- if (lnk->nextLink() != (Link*)nil) errDblLnk("add",*lnk);
- if (count == 0) firstLink = lnk;
- else lastLink->nextLink(lnk);
- lastLink = lnk;
- count++;
- return (Object*)&ob;
- }
-
- Collection& LinkedList::addContentsTo(Collection& cltn) const
- {
- register Link* p = firstLink;
- while (p != (Link*)nil) {
- register Link* t = (Link*)p->copy();
- t->nextLink((Link*)nil);
- cltn.add(*t);
- p = p->nextLink();
- }
- return cltn;
- }
-
- Object* LinkedList::addFirst(const Object& ob)
- {
- assertArgClass(ob,class_Link,"addFirst");
- if (count == 0) return add(ob);
- else {
- register Link* lnk = (Link*)&ob;
- if (lnk->nextLink() != (Link*)nil) errDblLnk("addFirst",*lnk);
- lnk->nextLink(firstLink);
- firstLink = lnk;
- count++;
- return (Object*)&ob;
- }
- }
-
- Object* LinkedList::addLast(const Object& ob) { return add(ob); }
-
- Object*& LinkedList::operator[](int i) const
- {
- if ((unsigned)i >= count) indexRangeErr();
- if (i==0) return (Object*)firstLink;
- else {
- register Link* p = firstLink;
- for (register int j=i-1; j>0; j--) p = p->nextLink();
- return (Object*)p->next;
- }
- }
-
- Object*& LinkedList::at(int i) const { return (*this)[i]; }
-
- void LinkedList::atAllPut(const Object&) { shouldNotImplement("atAllPut"); }
-
- void LinkedList::deepenShallowCopy()
- {
- BASE::deepenShallowCopy();
- register Link* p = firstLink;
- firstLink = lastLink = (Link*)nil;
- count = 0;
- while (p != (Link*)nil) {
- add(*(p->deepCopy()));
- p = p->nextLink();
- }
- }
-
- #pragma warn -rvl // Turn of Warning: Function should return a value
- Object* LinkedList::first() const
- {
- if (count==0)
- {
- errEmpty("first"); // aborts, return not executed
- // return (Object*)NULL; // avoids Warning message
- }else
- return firstLink;
- }
- #pragma warn .rvl
-
- unsigned LinkedList::hash() const
- {
- register unsigned h = count;
- register Link* p = firstLink;
- while (p != (Link*)nil) {
- h^= p->hash();
- p = p->nextLink();
- }
- return h;
- }
-
- int LinkedList::indexOf(const Object& ob) const
- {
- register int i = 0;
- register Link* p = firstLink;
- while (p != (Link*)nil) {
- if (p->isEqual(ob)) return i;
- p = p->nextLink();
- i++;
- }
- return -1;
- }
-
- int LinkedList::indexOfSubCollection(const SeqCltn& /*cltn*/,
- int /*start*/) const
- { shouldNotImplement("indexOfSubCollection"); return 0; }
-
- bool LinkedList::isEmpty() const { return count==0; }
-
- bool LinkedList::isEqual(const Object& a) const
- {
- return a.isSpecies(class_LinkedList) && *this==*(LinkedList*)&a;
- }
-
- const Class* LinkedList::species() const { return &class_LinkedList; }
-
- #pragma warn -rvl // Turn of Warning: Function should return a value
- Object* LinkedList::last() const
- {
- if (count==0)
- {
- errEmpty("last"); // aborts, return not executed
- // return (Object*)NULL; // avoids Warning message
- } else
- return lastLink;
- }
- #pragma warn .rvl
-
- Object* LinkedList::doNext(Iterator& pos) const
- {
- if (pos.ptr == 0) {
- if (firstLink == nil) return 0;
- else {
- pos.ptr = firstLink;
- pos.index = 1;
- return firstLink;
- }
- }
- else if ((Link*)pos.ptr == lastLink) return 0;
- else {
- pos.ptr = ((Link*)pos.ptr)->nextLink();
- pos.index++;
- return (Object*)pos.ptr;
- }
- }
-
- unsigned LinkedList::occurrencesOf(const Object& ob) const
- {
- register unsigned n=0;
- register Link* p = firstLink;
- while (p != (Link*)nil) {
- if (p->isEqual(ob)) n++;
- p = p->nextLink();
- }
- return n;
- }
-
- void LinkedList::printOn(ostream& strm) const
- {
- strm << className() << "[\n";
- register unsigned i = 0;
- register Link* p = firstLink;
- while (p != (Link*)nil) {
- if (i>0) strm << "\n";
- p->printOn(strm);
- p = p->nextLink();
- i++;
- }
- strm << "]\n";
- }
-
- Object* LinkedList::remove(const Object& ob)
- {
- assertArgClass(ob,class_Link,"remove");
- if (count==0) errEmpty("remove");
- register Link* lnk = (Link*)&ob;
- if (lnk == firstLink) {
- firstLink = lnk->nextLink();
- if (lnk == lastLink) lastLink = (Link*)nil;
- goto wrapup;
- }
- else {
- register Link* p = firstLink;
- while (p != (Link*)nil) {
- if (lnk == p->nextLink()) {
- p->nextLink(lnk->nextLink());
- if (lnk == lastLink) lastLink = p;
- goto wrapup;
- }
- p = p->nextLink();
- }
- errNotFound("remove",ob);
- }
- wrapup:
- lnk->nextLink((Link*)nil);
- count--;
- return (Object*)&ob;
- }
-
- Object* LinkedList::removeFirst() { return remove(*firstLink); }
-
- Object* LinkedList::removeLast() { return remove(*lastLink); }
-
- void LinkedList::replaceFrom(int /*start*/, int /*stop*/, const SeqCltn& /*replacement*/, int /*startAt*/)
- {
- shouldNotImplement("replaceFrom");
- }
-
- void LinkedList::reSize(unsigned /*newSize*/) {}
-
- unsigned LinkedList::size() const { return count; }
-
- void LinkedList::errDblLnk(const char* fn, const Link& lnk) const
- {
- DTerror("", "");
- cerr << "Attempt to add " << lnk.className()
- << " to two " << className() << "s: "
- << this << "->"
- << className() << "::" << fn
- << "((" << lnk.className() << "*)"
- << &lnk << ")"
- << "\n";
- }
-
- void LinkedList::errEmpty(const char* fn) const
- {
- DTerror("", "");
- cerr << "Collection empty: "
- << this << "->"
- << className() << "::" << fn << "()"
- << "\n";
- }
-
- void LinkedList::errNotFound(const char* fn, const Object& ob) const
- {
- DTerror("", ""); // non fatal
- cerr << "Object not found: "
- << this << "->"
- << className() << "::" << fn
- << "((" << ob.className() << "*)"
- << &ob << ")"
- << "\n";
- }
-
-